// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2007
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class Morphology
    {
        #region Flag
        private string flag = "[Image -> Morphology -> GVFThinning]";
        public string Flag() { return flag; }
        #endregion

        #region Field
        private PZPoint expandPoint;
        //private PZMath_matrix kernal;
        #endregion

        #region Property
        public PZPoint P { set { expandPoint = value; } get { return expandPoint; } }
        #endregion

        #region apply
        public Bitmap ExpandAt(Bitmap srcImage, PZPoint p, int kernalSize)
        {
            // valid check
            int height = srcImage.Height;
            int width = srcImage.Width;
            if (p.x < 0 || p.x >= width || p.y < 0 || p.y >= height)
                throw new ApplicationException("Morphology::ExpandAt(), point out side image!");
            // prepare kernal
            int kernalHalf = kernalSize / 2;
            // assume white background
            Bitmap dstImage = new Bitmap(srcImage);
            int px = (int) p.x;
            int py = (int) p.y;
            for (int i = 0; i < kernalSize; i++)
            {
                for (int j = 0; j < kernalSize; j++)
                {
                    int cx = px - i + kernalHalf;
                    int cy = py - j + kernalHalf;
                    if (cx < 0 || cx >= width || cy < 0 || cy >= height)
                        continue;
                    dstImage.SetPixel(cx, cy, Color.Black);
                }
            }
            return dstImage;
        } // ExpandAt()
        public Bitmap ExpandAt(Bitmap srcImage, PZPoint p)
        {
            return ExpandAt(srcImage, p, 5);
        }
        public Bitmap ErodAt(Bitmap srcImage, PZPoint p, int kernalSize)
        {
            // valid check
            int height = srcImage.Height;
            int width = srcImage.Width;
            if (p.x < 0 || p.x >= width || p.y < 0 || p.y >= height)
                throw new ApplicationException("Morphology::ExpandAt(), point out side image!");
            // prepare kernal
            int kernalHalf = kernalSize / 2;
            // assume white background
            Bitmap dstImage = new Bitmap(srcImage);
            int px = (int)p.x;
            int py = (int)p.y;
            for (int i = 0; i < kernalSize; i++)
            {
                for (int j = 0; j < kernalSize; j++)
                {
                    int cx = px - i + kernalHalf;
                    int cy = py - j + kernalHalf;
                    if (cx < 0 || cx >= width || cy < 0 || cy >= height)
                        continue;
                    dstImage.SetPixel(cx, cy, Color.White);
                }
            }
            return dstImage;
        } // ErodAt()
        public Bitmap ErodAt(Bitmap srcImage, PZPoint p)
        {
            return ErodAt(srcImage, p, 5);
        }
        private PZMath_matrix Prepare5By5Kernal()
        {
            PZMath_matrix k = new PZMath_matrix(5, 5);
            k[0, 2] = 1.0;
            k[1, 1] = 1.0;
            k[1, 2] = 1.0;
            k[1, 3] = 1.0;
            for (int i = 0; i < 5; i++)
                k[2, i] = 1.0;
            k[3, 1] = 1.0;
            k[3, 2] = 1.0;
            k[3, 3] = 1.0;
            k[4, 2] = 1.0;
            return k;
        }
        #endregion
    }
}
